//*****************************************************************************

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h"
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
unsigned long ulPeriod, dutyCycle;
//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************

void UARTIntHandler(void) {
	unsigned long ulStatus;
	char c;

	//
	// Get the interrrupt status.
	//
	ulStatus = ROM_UARTIntStatus(UART1_BASE, true);

	//
	// Clear the asserted interrupts.
	//
	ROM_UARTIntClear(UART1_BASE, ulStatus);

	//
	// Loop while there are characters in the receive FIFO.
	//

	while (ROM_UARTCharsAvail(UART1_BASE)) {
		//
		// Read the next character from the UART and write it back to the UART.
		//
		/*ROM_UARTCharPutNonBlocking(UART1_BASE,
				ROM_UARTCharGetNonBlocking(UART1_BASE));*/

		//
		// Blink the LED to show a character transfer is occuring.
		//
		//SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
		//TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
		TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);
		TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle); // PWM
		TimerEnable(TIMER0_BASE, TIMER_A);
		c = UARTCharGet(UART1_BASE);
		if (c==53) {

					int j = 0;
					ulPeriod = 50;
					//dutyCycle = ulPeriod / 20;
					dutyCycle=2.5;
					TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);
					TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle); // PWM
					TimerEnable(TIMER0_BASE, TIMER_A);

					while (j < 300000) {

						TimerEnable(TIMER0_BASE, TIMER_A);
						SysCtlDelay(ulPeriod / 3);
						TimerDisable(TIMER0_BASE, TIMER_A);
						SysCtlDelay(ulPeriod - (ulPeriod / 3));
						j++;
					}

					//return;
				}

				if (c ==54) {
					int i = 0;

					i = 0;
					ulPeriod = 50;
					//dutyCycle = ulPeriod / 10;
					dutyCycle=5;
					TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);
					TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle); // PWM
					//TimerEnable(TIMER0_BASE, TIMER_A);
					while (i < 300000) {

						TimerEnable(TIMER0_BASE, TIMER_A);
						SysCtlDelay(ulPeriod / 3);
						TimerDisable(TIMER0_BASE, TIMER_A);
						SysCtlDelay(ulPeriod - (ulPeriod / 3));
						i++;
					}

					//return;
				}
		if (c==48)
					{
			        /*

							unsigned char *pucBuffer = "\033 "+port1;
							unsigned long ulCount = 12;
							while (ulCount--) {
								ROM_UARTCharPutNonBlocking(UART1_BASE, *pucBuffer++);
							}*/
					//return;
					}
		if (c ==49) {

						GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 2);

						//return;

				}
				if (c ==50) {

					GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);

					//return;

				}
				if (c == 51) {

								GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
															  }
								//return;
						}
				if (c == 52) {

							GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);

							//return;
						}
				           char *pucBuffer;

                         int  port1=0;
                         int port2=0;
                         int port3=0;
										port1 = GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1);
										port2 = GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2);
										port3 = GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_6);
                                        if (port1>0)
                                           if (port2>0)
                                        	   if (port3>0) pucBuffer = "\033 111\n";
                                        	   else pucBuffer = "\033 110\n";
                                           else if (port3>0) pucBuffer = "\033 101\n";
                                    	        else pucBuffer = "\033 100\n";
                                        else if (port2>0)
                                     	   if (port3>0) pucBuffer = "\033 011\n";
                                     	   else pucBuffer = "\033 010\n";
                                        else if (port3>0) pucBuffer = "\033 001\n";
                                 	        else pucBuffer = "\033 000\n";



										unsigned long ulCount = 6;
										while (ulCount--) {
										      ROM_UARTCharPutNonBlocking(UART1_BASE, *pucBuffer++);
														  }

}

//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void UARTSend(const unsigned char *pucBuffer, unsigned long ulCount) {
	//
	// Loop while there are more characters to send.
	//
	while (ulCount--) {
		//
		// Write the next character to the UART.
		//
		ROM_UARTCharPutNonBlocking(UART1_BASE, *pucBuffer++);
	}
}

//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int main(void) {
	//
	// Enable lazy stacking for interrupt handlers.  This allows floating-point
	// instructions to be used within interrupt handlers, but at the expense of
	// extra stack usage.
	//

	ROM_FPUEnable();
	ROM_FPULazyStackingEnable();

	// 40 MHz system clock
	SysCtlClockSet(
			SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ
					| SYSCTL_OSC_MAIN);
	//
	// Set the clocking to run directly from the crystal.
	//

	ulPeriod = SysCtlClockGet() / 800000;
	dutyCycle = ulPeriod / 2;
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	GPIOPinConfigure(GPIO_PB6_T0CCP0);
	GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_6);

	// Configure timer
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
	TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
	TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);
	TimerMatchSet(TIMER0_BASE, TIMER_A, dutyCycle); // PWM
	//TimerEnable(TIMER0_BASE, TIMER_A);

	//
	// Enable the GPIO port that is used for the on-board LED.
	//
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

	//
	// Enable the GPIO pins for the LED (PF2).
	//
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,
			GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

	//
	// Enable the peripherals used by this example.
	//
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

	//
	// Enable processor interrupts.
	//
	ROM_IntMasterEnable();

	//
	// Set GPIO A0 and A1 as UART pins.
	//
	GPIOPinConfigure(GPIO_PB0_U1RX);
	GPIOPinConfigure(GPIO_PB1_U1TX);
	ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

	//
	// Configure the UART for 115,200, 8-N-1 operation.
	//
	ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 9600,
			(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

	//
	// Enable the UART interrupt.
	//
	ROM_IntEnable(INT_UART1);
	ROM_UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT);

	// Configure PB6 as T0CCP0
	//UARTSend((unsigned char *) "\033 Hello", 7);
	while (1) {
	}
}
